home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
gfx
/
3d
/
rayshade40_enh2.lha
/
ENHANCE
/
zbuf.doc
< prev
Wrap
Text File
|
1992-04-28
|
5KB
|
135 lines
*** Adding Z Buffer output to Rayshade 4.0 ***
Mark Maimone, mwm@cs.cmu.edu (BITNET: mwm%cs.cmu.edu@CARNEGIE)
18 March 1992
I've made a preliminary attempt at getting Rayshade to output depth
information in addition to rendered images. I need this information since I
want to use Rayshade to generate test images for a stereo algorithm. Having
the "true" depth means I can test how accurately my stereo algorithm
reconstructs it (depth) from only the stereo pair of 2D images without
knowing the inherent 3D structure.
My technique is quite basic. I rely on the anti-aliasing scheme to
sample the pixels, and remember the distance from the Eye to the nearest
object along each generated ray. Of all these distances associated with a
pixel, I arbitrarily choose the one nearest to the eye to denote the "true"
distance.
This scheme has several problems (and I'm sure others will find
more). It doesn't return the distance of the object that occupies *most* of
the pixel, it merely returns the distance of the object it finds nearest to
the eye; it doesn't matter if it only occupies 5% of the pixel. It lets the
antialiasing scheme choose which rays are relevant; a bad antialiasing
scheme may well yield a bad Z buffer. It treats transparent objects as
opaque (changing this *should* only require adding a very simple test in
trace_pixel(), but I don't know enough about the internals yet). It assumes
all distances are positive (this, at least, should be a reasonable
assumption).
The changes were realized entirely within the
"rayshade-4.0/rayshade" directory. No changes were made to the libraries.
Adding the Z buffer to rayshade involves several small changes to files in
that directory, plus the addition of two more (short) source files, zbuf.c
and zbuf.h.
======== COMMAND LINE INTERFACE
Very easy. Just run rayshade with the "-z filename" option to write
the Z buffer to the named file. You must name some file, it won't write to
stdout.
======== IMPLEMENTATION
Rayshade-4.0 already computes everything needed to generate the Z
buffer, but it throws the information away. I've added an external Float
array (zbuffer in zbuf.c) to store the distance to the nearest object in
each pixel. You must have enough memory available for a Float array with
the same dimensions as the window being rendered.
I put a hook into the routine where Rayshade finds the "first"
object hit by a given ray (trace_pixel() in rayshade/raytrace.c). That hook
calls ZbufAdd() to store the current distance in global array zbuffer.
ZbufAdd() maps the Float index values to ints by using floor(pix+0.5) for
both X and Y.
======== FILE FORMAT
The first few lines in the file are comments describing the source
of the data. After that, the depth information follows, with each line
representing a single pixel:
<int x-coord> <int y-coord> <Float distance>
A distance of -1 means the pixel denotes background. The file is ordered by
scanline, with a blank line separating scanlines. This format is ideally
suited for viewing the depth map using GNUplot (see comments in zbuf.c).
Here's a sample output file:
# Depth Map for Rayshade output file
# Input RAY file: "../Examples/planet.ray"
# Resolution for this rendering is 50x50
# window from (0,0) to (49,49)
# Index 0: 11412 hits
0 0 -1
0 1 -1
0 2 -1
0 3 -1
. [ I deleted many lines for brevity ]
.
12 13 -1
12 14 -1
12 15 -1
12 16 3.75485
12 17 3.60294
12 18 3.52262
12 19 3.46714
12 20 3.42647
12 21 3.40308
======== COMMENTS
Please post any comments to the rayshade-users@cs.princeton.edu
mailing list, or if you prefer you may send them directly to me at
mwm@cs.cmu.edu. Any comments are welcome, especially ones of the form "your
scheme for computing the Z buffer is useless because...."
Mark Maimone
CMU Computer Science
mwm@cs.cmu.edu
======== EXAMPLES
% rayshade -R 50 50 -z zbuf.dat Examples/balls.ray > balls.rle
% gnuplot
gnuplot> set term x11 [or whatever you're on]
gnuplot> set sample 2500 [for a 50x50 image]
gnuplot> set parametric [needed to plot 3D data]
gnuplot> splot 'zbuf.dat' with lines
[gives a nice height map grid]
gnuplot> help set view [info on changing viewpoint]
gnuplot> set view 45, 45 [a sample viewpoint]
gnuplot> quit
Warning! Distances are expected to always be positive, so background
pixels are represented by a distance of ZBUF_INF (i.e., -1). To get
nice looking GNUplot output you should replace all -1's with the maximum
distance. On UNIX:
% rayshade -R 50 50 -z zbuf.dat Examples/planet.ray > balls.rle
% awk 'BEGIN {max = -1} NF == 3 { if ($3 > max) max = $d} END \
{print max}' < zbuf.dat [this gives you the max]
3.69359
% sed s/-1/3.69359/g < zbuf.dat | awk 'NF == 3 { print $1" "$2" -"$3 \
; next} {print}' > zbuf.plot [replace -1 with max, make all
distances negative so the
plot appears rightside up]
% gnuplot
.
.
gnuplot> set zrange [-3.7:0]
gnuplot> splot 'zbuf.plot'